package cz.tomasdvorak.cars.utils;

import java.util.*;

/**
 * Pomocne metody pro praci s mnozinami.
 */
public class Sets {
    /**
     * Vytvori {@link HashSet} ze vsech zadanych hodnot, ktere nejsou {@code null}.
     * Nikdy nevraci {@code null} a nevyhazuje NPE.
     */
    public static <T> HashSet<T> hashSet(T... values) {
        return hashSet(values == null ? Collections.<T>emptyList() : Arrays.asList(values));
    }

    /**
     * Vytvori {@link HashSet} ze vsech zadanych hodnot, ktere nejsou {@code null}.
     * Nikdy nevraci {@code null} a nevyhazuje NPE.
     */
    public static <T> HashSet<T> hashSet(Collection<? extends T> values) {
        HashSet<T> result = new HashSet<T>();
        if (values != null) {
            for (T value : values) {
                if (value != null) {
                    result.add(value);
                }
            }
        }
        return result;
    }

    /**
     * Vytvori mnozinu cisel, ktera obsahuje vsechny nezaporne hodnoty z dane mnoziny. Nikdy
     * nevraci {@code null} a nevyhazuje NPE.
     */
    public static <T extends Number> Set<T> withoutNegatives(Set<? extends T> set) {
        Set<T> result = hashSet(set);
        for (Iterator<T> it = result.iterator(); it.hasNext();) {
            T num = it.next();
            if (num == null || num.longValue() < 0) {
                it.remove();
            }
        }
        return result;
    }

    /**
     * Vytvori {@link LinkedHashSet} ze vsech zadanych hodnot, ktere nejsou {@code null}.
     * Nikdy nevraci {@code null} a nevyhazuje NPE.
     */
    public static <T> LinkedHashSet<T> linkedHashSet(T... values) {
        return linkedHashSet(values == null ? Collections.<T>emptyList() : Arrays.asList(values));
    }

    /**
     * Vytvori {@link LinkedHashSet} ze vsech zadanych hodnot, ktere nejsou {@code null}.
     * Nikdy nevraci {@code null} a nevyhazuje NPE.
     */
    public static <T> LinkedHashSet<T> linkedHashSet(Collection<? extends T> values) {
        LinkedHashSet<T> result = new LinkedHashSet<T>();
        if (values != null) {
            for (T value : values) {
                if (value != null) {
                    result.add(value);
                }
            }
        }
        return result;
    }

    /**
     * Vytvori {@link TreeSet} ze vsech zadanych hodnot, ktere nejsou {@code null}.
     * Nikdy nevraci {@code null} a nevyhazuje NPE.
     */
    public static <T> TreeSet<T> treeSet(T... values) {
        return treeSet(values == null ? Collections.<T>emptyList() : Arrays.asList(values));
    }

    /**
     * Vytvori {@link TreeSet} ze vsech zadanych hodnot, ktere nejsou {@code null}.
     * Nikdy nevraci {@code null} a nevyhazuje NPE.
     */
    public static <T> TreeSet<T> treeSet(Collection<? extends T> values) {
        TreeSet<T> result = new TreeSet<T>();
        if (values != null) {
            for (T value : values) {
                if (value != null) {
                    result.add(value);
                }
            }
        }
        return result;
    }
}
